package com.fucking.great.context.single;

import cn.hutool.core.util.ReflectUtil;
import com.fucking.great.context.TxnContext;
import com.fucking.great.context.common.CallService;
import com.fucking.great.context.config.CacheTxnConfigerDecorator;
import com.fucking.great.context.config.TxnConfiger;
import com.fucking.great.context.constant.EnvConstant;
import com.fucking.great.context.engine.Engine;
import com.fucking.great.context.engine.GroovyClassLoaderCacheEngine;
import com.fucking.great.context.engine.GroovyClassLoaderEngine;
import com.fucking.great.context.util.SingleUtil;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

/**
 * 建议使用这个类，分debug和service，2个环境去实例化对象。
 * @see GreatSingleFactory#newInstanse
 */
public class GreatSingleFactory implements SingleFactory {
    @Override
    public Map<String,Object> getNeedRegsigAllBean(Map<String,Object> storageCenter) {
        //
        Map<String, Object> map = new HashMap<>();

        // 以下都是如果存在,则不往里面放了。
        TxnConfiger concreteComponent = ReflectUtil.newInstance(EnvConstant.CONCRETE_TXNCONFIGER_CLASS_NAME);

        // txnConfiger
        this.newInstanse(TxnConfiger.class,storageCenter,map,
                () ->  new CacheTxnConfigerDecorator(concreteComponent) ,
                () ->  concreteComponent );
        // engine
        this.newInstanse(Engine.class,storageCenter,map,
                () ->  new GroovyClassLoaderCacheEngine() ,
                () ->   new GroovyClassLoaderEngine() );
        // callService 不存在才放入.
        map.putIfAbsent( SingleUtil.classToKey(CallService.class) ,new CallService());
        //
        return map;
    }

    /**
     *
     * @param type 类名
     * @param storageCenter 存储中心
     * @param map   临时的map
     * @param serviceBean 返回service的bean
     * @param debugBean 返回debug的bean
     */
    public final void newInstanse(Class type,Map<String,Object> storageCenter,Map<String, Object> map,Supplier<Object> serviceBean, Supplier<Object> debugBean){
        String engineName = SingleUtil.classToKey(type);

        // 如果不存在,才放入。
        if (!storageCenter.containsKey(engineName)) {
            Object engine = null;
            if (TxnContext.IS_SERVICE) {
                engine = serviceBean.get();
            }else{
                engine = debugBean.get();
            }
            map.put(engineName,engine);
        }
    }

}
